package my;

import my.common.File;
import my.epoll.EventArray;
import my.epoll.Native;
import my.socket.ServerSocket;
import my.socket.Socket;

import java.io.IOException;

/**
 * @author fengbo
 */
public class ServerBootstrap {

    private EpollEventLoopGroup workers;

    private ServerBootstrap() {}

    private static final ServerBootstrap BOOTSTRAP = new ServerBootstrap();

    public static ServerBootstrap getInstance() {
        return BOOTSTRAP;
    }

    public ServerBootstrap group(EpollEventLoopGroup workers) {
        this.workers = workers;
        return this;
    }

    public ServerBootstrap bind(int port) {
        if (workers == null) {
            throw new IllegalStateException("Work group is null");
        }
        ServerSocket serverSocket = null;
        int efd = 0;
        try {
            serverSocket = new ServerSocket(port);
            EventArray events = new EventArray(1024);
            efd = Native.epollCreate();
            Native.epollCtlAdd(efd, serverSocket.intValue(), Native.EPOLLIN);
            for (;;) {
                int ready = Native.epollWait(efd, events, 0);
                for (int i = 0; i < ready; i++) {
                    int fd = events.fd(i);
                    if (serverSocket.intValue() == fd) {
                        Socket socket = serverSocket.accept();
                        workers.register(socket);
                    }
                }
            }
        } catch (IOException e) {
            throw new IllegalStateException("Bind failed", e);
        } finally {
            if (serverSocket != null) {
                serverSocket.close();
            }
            if (efd > 0) {
                File.close(efd);
            }
        }
    }
}
